using System;
using System.Buffers;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SuperSocket;
using SuperSocket.Command;
using SuperSocket.ProtoBase;

namespace MoolinkHsmsServer
{
    public class HsmsMessageFilter : FixedHeaderPipelineFilter<HsmsMessage>
    {
        //private bool _foundHeader;
        //private readonly int _headerSize;
        //private int _totalSize;

        /// <summary>
        /// Header size is 5
        /// 1: OpCode
        /// 2-3: body length
        /// 4-5: sequence
        /// </summary>
        public HsmsMessageFilter()
            : base(14)
        {
            //_headerSize = 14;
        }

        protected override int GetBodyLengthFromHeader(ref ReadOnlySequence<byte> buffer)
        {
            var reader = new SequenceReader<byte>(buffer);

            //reader.Advance(1); // skip the first byte for OpCode
            reader.TryReadBigEndian(out int len);
            //reader.Advance(14); // skip the two bytes for Sequence
            //Console.Write($".Length [{len}].");
            return len-10;
        }




        //public override HsmsMessage Filter(ref SequenceReader<byte> reader)
        //{
        //    if (!_foundHeader)
        //    {
        //        if (reader.Length < _headerSize)
        //            return null;

        //        var header = reader.Sequence.Slice(0, _headerSize);
        //        var bodyLength = GetBodyLengthFromHeader(ref header);

        //        if (bodyLength < 0)
        //            throw new ProtocolException("Failed to get body length from the package header.");

        //        if (bodyLength == 0)
        //        {
        //            try
        //            {
        //                return DecodePackage(ref header);
        //            }
        //            finally
        //            {
        //                reader.Advance(_headerSize);
        //            }
        //        }

        //        _foundHeader = true;
        //        _totalSize = _headerSize + bodyLength;
        //    }

        //    var totalSize = _totalSize;

        //    if (reader.Length < totalSize)
        //        return null;

        //    var pack = reader.Sequence.Slice(0, totalSize);

        //    try
        //    {
        //        return DecodePackage(ref pack);
        //    }
        //    finally
        //    {
        //        reader.Advance(totalSize);
        //    }
        //}
        protected override HsmsMessage DecodePackage(ref ReadOnlySequence<byte> buffer)
        {
            var reader = new SequenceReader<byte>(buffer);
            var package = new HsmsMessage(reader.Sequence.Length - 14);

            reader.Sequence.Slice(0, 4).CopyTo(package.LengthFrame.Bytes.AsSpan());
            reader.Sequence.Slice(4, 10).CopyTo(package.HeaderFrame.Bytes.AsSpan());

            //Console.Write($"MaxMsgBodyLength [{package.TextFrame.MaxMsgBodyLength}].");
            if (package.TextFrame.MaxMsgBodyLength > 0)
			{
                reader.Sequence.Slice(14, package.TextFrame.MaxMsgBodyLength).CopyTo(package.TextFrame.Bytes.AsSpan());
            }


			return package;
        }


    }

}